package com.tqjc.business.interactivewithscan.uils;



import com.tqjc.business.interactivewithscan.consts.CoordConstant;
import com.tqjc.business.interactivewithscan.entity.*;

import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 坐标工具类
 */
public class CoordUtils {
    /**
     * 吸料点的获取
     *
     * @param rangeList 范围内DME
     * @param range     范围界限
     * @param query     条件
     * @return
     */
    public static Coord grabCoord(List<Coord> rangeList, QuadrilateralVertex range, CoordQuery query) {
        // 该区域以作操作，本次剔除该区域
        if (query.getOtherCoord() != null) {
            QuadrilateralVertex cp = CoordinatesUtils.queryVertex(query.getOtherCoord(), query.getOtherDevice().getLength() / 2, query.getOtherDevice().getWidth() / 2);
            Iterator<Coord> iterator = rangeList.iterator();
            while (iterator.hasNext()) {
                Coord rangeCoord = iterator.next();
                if (CoordinatesUtils.pointInsideRectangle(cp, rangeCoord)) {
                    iterator.remove();
                }
            }
        }
        range.setSafeDistance(0);
        // 分层
        List<List<Coord>> layers = CoordinatesUtils.layers(rangeList, query.getFloorHeight(), true);
        layers = layers.stream().filter(layer -> layer.size() >= query.getSeveral()).collect(Collectors.toList());
        int symbolX = (query.getType() % 4 == 1 || query.getType() % 4 == 2 ? 1 : -1) * query.getThisDevice().getLength() / 2;
        int symbolY = (query.getType() % 4 == 1 || query.getType() % 4 == 3 ? 1 : -1) * query.getThisDevice().getWidth() / 2;
        for (List<Coord> layer : layers) {
            layer.sort(new CoordSortForXY(query.getType()));
            Iterator<Coord> layerIterator = layer.iterator();
            while (layerIterator.hasNext()) {
                Coord coord = layerIterator.next();
                Coord center = new Coord(coord.getX() + symbolX, coord.getY() + symbolY, 0);
                QuadrilateralVertex sv = CoordinatesUtils.queryVertex(center, Math.abs(symbolX), Math.abs(symbolY));
                List<Coord> screens = CoordinatesUtils.screenDesignationRegion(sv, layer);
                if (screens.size() >= query.getSeveral()) {
                    Coord correction = CoordinatesUtils.centerCorrection(screens, range, Math.abs(symbolX), Math.abs(symbolY));
                    correction.setTestX(center.getX());
                    correction.setTestY(center.getY());
                    return correction;
                }
            }
        }
        return null;
    }

    /**
     * 卸料点获取
     *
     * @param rangeList 范围内DME
     * @param range     范围界限
     * @param query     条件
     * @param type      true：库区卸料，false：槽车卸料
     * @return
     */
    public static Coord dischargeCoord(List<Coord> rangeList, QuadrilateralVertex range, CoordQuery query, boolean type) {

//        System.out.println(query.toString());
//        System.out.println(range.toString());
        Integer miz = type ? CoordConstant.Maximum_Height_To_Top : CoordConstant.Tanker_Safe_Height;
        Integer maz = type ? CoordConstant.Maximum_Height_To_Ground : CoordConstant.Maximum_Height_To_Tanker;
        // 该区域以作操作，本次剔除该区域
//        if (query.getOtherCoord() != null) {
//            QuadrilateralVertex cp = CoordinatesUtils.queryVertex(query.getOtherCoord(), query.getOtherDevice().getLength() / 2, query.getOtherDevice().getWidth() / 2);
//            Iterator<Coord> iterator = rangeList.iterator();
//            while (iterator.hasNext()) {
//                Coord rangeCoord = iterator.next();
//                if (CoordinatesUtils.pointInsideRectangle(cp, rangeCoord)) {
//                    rangeCoord.setZ(miz);
//                }
//            }
//        }
//        range.setSafeDistance(0);

//        System.out.println(rangeList);
        int symbolX = query.getType() % 4 == 1 || query.getType() % 4 == 2 ? 1 : -1;
        int symbolY = query.getType() % 4 == 1 || query.getType() % 4 == 3 ? 1 : -1;
        int symbolForX = symbolX * query.getThisDevice().getLength();
        int symbolForY = symbolY * query.getThisDevice().getWidth();

        int startX = query.getType() % 4 == 1 || query.getType() % 4 == 2 ? range.getMinX() : range.getMaxX();
        int endX = query.getType() % 4 == 1 || query.getType() % 4 == 2 ? range.getMaxX() : range.getMinX();
        int startY = query.getType() % 4 == 1 || query.getType() % 4 == 3 ? range.getMinY() : range.getMaxY();
        int endY = query.getType() % 4 == 1 || query.getType() % 4 == 3 ? range.getMaxY() : range.getMinY();
        if (query.getType() <= 4) {

            for (int z = maz; z > miz; z = z - query.getFloorHeight()) {
//                System.out.println("开始生成");
                for (int x = startX; (endX - x + symbolForX) * symbolX >= 0; x = x + 200 * symbolX) {
                    Coord centerTemp = new Coord(x + symbolForX / 2, (startY + endY) / 2, 0);
                    QuadrilateralVertex sc = CoordinatesUtils.queryVertex(centerTemp, Math.abs(symbolForX / 2), (startY + endY) / 2);
                    List<Coord> screensTemp = CoordinatesUtils.screenDesignationRegion(sc, rangeList);
                    List<Coord> tempList = CoordinatesUtils.queryRangeHeight(screensTemp, z - query.getFloorHeight(), z);
                    if (tempList.size() == 0) {
                        continue;
                    }
                    System.out.println("startY"+startY);
                    for (int y = startY; (endY - y + symbolForY) * symbolY >= 0; y = y + 200 * symbolY) {
                        Coord center = new Coord(x + symbolForX / 2, y + symbolForY / 2, 0);
//                        System.out.println(center.toString());
                        QuadrilateralVertex sv = CoordinatesUtils.queryVertex(center, Math.abs(symbolForX / 2), Math.abs(symbolForY / 2));
                        List<Coord> screens = CoordinatesUtils.screenDesignationRegion(sv, rangeList);
                        int h = screens.stream().min(new CoordSort(query.getType())).orElse(new Coord()).getZ();
//                        System.out.println("h+"+h);
                        if (h < z - query.getFloorHeight()) {
                            List<Coord> temps = CoordinatesUtils.queryRangeHeight(screens, z - query.getFloorHeight(), z);
                            if (temps.size() == 0) {
                                continue;
                            }
                            temps.sort(new CoordSort(3));
                            y = symbolY > 0 ? temps.get(0).getY() : temps.get(temps.size() - 1).getY();
                            continue;
                        }
                        center.setZ(h);
                        System.out.println("h+"+h);
                        return center;
                    }
                    tempList.sort(new CoordSort(2));
                    x = startX > 0 ? tempList.get(0).getX() : tempList.get(tempList.size() - 1).getX();
                }
            }
        } else {
            for (int z = maz; z > miz; z = z - query.getFloorHeight()) {
                for (int y = startY; (endY - y + symbolForY) * symbolY >= 0; y = y + 200 * symbolY) {
                    Coord centerTemp = new Coord((startX + endX) / 2, y + symbolForY / 2, 0);
                    QuadrilateralVertex sc = CoordinatesUtils.queryVertex(centerTemp, (startX + endX) / 2, Math.abs(symbolForY / 2));
                    List<Coord> screensTemp = CoordinatesUtils.screenDesignationRegion(sc, rangeList);
                    List<Coord> tempList = CoordinatesUtils.queryRangeHeight(screensTemp, z - query.getFloorHeight(), z);
                    for (int x = startX; (endX - x + symbolForX) * symbolX >= 0; x = x + 200 * symbolX) {
                        Coord center = new Coord(x + symbolForX / 2, y + symbolForY / 2, 0);
                        QuadrilateralVertex sv = CoordinatesUtils.queryVertex(center, Math.abs(symbolForX / 2), Math.abs(symbolForY / 2));
                        List<Coord> screens = CoordinatesUtils.screenDesignationRegion(sv, rangeList);
                        int h = screens.stream().min(new CoordSort(4)).orElse(new Coord()).getZ();
                        if (h < z - query.getFloorHeight()) {
                            List<Coord> temps = CoordinatesUtils.queryRangeHeight(screens, z - query.getFloorHeight(), z);
                            if (temps.size() == 0) {
                                continue;
                            }
                            temps.sort(new CoordSort(2));
                            x = symbolX > 0 ? temps.get(0).getX() : temps.get(temps.size() - 1).getX();
                            continue;
                        }
                        center.setZ(h);
                        return center;
                    }
                    tempList.sort(new CoordSort(3));
                    y = symbolY > 0 ? tempList.get(0).getY() : tempList.get(tempList.size() - 1).getY();
                }
            }
        }
        return null;
    }

    /**
     * 指定X轴范围内Z的最高高度
     *
     * @param rangeList 完整DME
     * @param start     起始x位置
     * @param end       结束x位置
     * @return
     */
    public static int specifyMaximum(List<Coord> rangeList, int start, int end) {
        if (start > end) {
            int t = end;
            end = start;
            start = t;
        }
        int height = 20000;
        for (Coord coord : rangeList) {
            if (coord.getX() >= start && coord.getX() <= end && coord.getZ() < height) {
                height = coord.getZ();
            }
        }
        return height;
    }
}
